# FindPETSc
# ---------
#
# Locates the PETSc library using pkg-config module PETSc
#
# Imported Targets
# ^^^^^^^^^^^^^^^^
#
# This module defines the following IMPORTED target:
#
#  PETSc::PETSc        - the PETSc library
#
# Result Variables
# ^^^^^^^^^^^^^^^^
#
# This module will set the following variables in your project:
#
#  PETSc_FOUND          - if false, do not try to link to PETSc
#  PETSc_LIBRARIES      - a list of the full paths to all libraries
#  PETSc_INCLUDE_DIRS   - a list of all include directories
#  PETSc_VERSION        - the full version of PETSc MAJOR.MINOR.PATCH
#  PETSc_VERSION_MAJOR  - the MAJOR part of PETSc_VERSION
#  PETSc_VERSION_MINOR  - the MINOR part of PETSc_VERSION
#  PETSc_VERSION_PATCH  - the PATCH part of PETSc_VERSION
#
# Setting these changes the behavior of the search
#  PETSC_DIR - directory in which PETSc resides
#  PETSC_ARCH - build architecture
#
# Author: Frédéric Simonis @fsimonis
# Improver: Nene Lee
# 
# References:
# - https://petsc.org/release/faq/#can-i-use-cmake-to-build-my-own-project-that-depends-on-petsc
# - https://petsc.org/release/manual/getting_started/#sec-writing-application-codes
# - https://github.com/precice/precice/blob/develop/cmake/modules/FindPETSc.cmake
# - https://github.com/oofem/oofem/blob/master/cmake/Modules/FindPETSc.cmake
#

cmake_policy(VERSION 3.10)

set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

# set root of location to find PETSc's pkg-config
set(PETSC $ENV{PETSC_DIR}/$ENV{PETSC_ARCH})
set(ENV{PKG_CONFIG_PATH} ${PETSC}/lib/pkgconfig)

# Remove the lines below if you do not wish to have PETSc determine the compilers
execute_process ( COMMAND pkg-config PETSc --variable=ccompiler COMMAND tr -d '\n' OUTPUT_VARIABLE C_COMPILER)
SET(CMAKE_C_COMPILER ${C_COMPILER})
execute_process ( COMMAND pkg-config PETSc --variable=cxxcompiler COMMAND tr -d '\n' OUTPUT_VARIABLE CXX_COMPILER)
if (CXX_COMPILER)
  SET(CMAKE_CXX_COMPILER ${CXX_COMPILER})
endif (CXX_COMPILER)
execute_process ( COMMAND pkg-config PETSc --variable=fcompiler COMMAND tr -d '\n' OUTPUT_VARIABLE FORTRAN_COMPILER)
if (FORTRAN_COMPILER)
  SET(CMAKE_Fortran_COMPILER ${FORTRAN_COMPILER})
  enable_language(Fortran)
endif (FORTRAN_COMPILER)

find_package(PkgConfig REQUIRED)

if(PKG_CONFIG_FOUND)
  pkg_search_module(PETSc REQUIRED IMPORTED_TARGET petsc)

  # Extract version parts from the version information
  if(PETSc_VERSION)
    set(_petsc_versions "")
    string(REGEX MATCHALL "[0-9]+" _petsc_versions ${PETSc_VERSION})
    list(GET _petsc_versions 0 _petsc_version_major)
    list(GET _petsc_versions 1 _petsc_version_minor)
    list(GET _petsc_versions 2 _petsc_version_patch)

    set(PETSc_VERSION ${PETSc_VERSION} CACHE STRING "Full version of PETSc")
    set(PETSc_VERSION_MAJOR ${_petsc_version_major} CACHE INTERNAL "Major version of PETSc")
    set(PETSc_VERSION_MINOR ${_petsc_version_minor} CACHE INTERNAL "Minor version of PETSc")
    set(PETSc_VERSION_PATCH ${_petsc_version_patch} CACHE INTERNAL "Patch version of PETSc")

    unset(_petsc_versions)
    unset(_petsc_version_major)
    unset(_petsc_version_minor)
    unset(_petsc_version_patch)
  endif()  
endif()

include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (PETSc
  REQUIRED_VARS PETSc_FOUND PETSc_INCLUDE_DIRS PETSc_LIBRARIES
  VERSION_VAR PETSc_VERSION
  )

if(NOT TARGET PETSc::PETSc)
  add_library(PETSc::PETSc ALIAS PkgConfig::PETSc)
endif()

mark_as_advanced(PETSc_INCLUDE_DIRS PETSc_LIBRARIES PETSc_VERSION_MAJOR PETSc_VERSION_MINOR PETSc_VERSION_PATCH VERSION_VAR PETSc_VERSION)
